[ML] Add per-PR changelog YAML entries with schema validation#2920
[ML] Add per-PR changelog YAML entries with schema validation#2920edsavage wants to merge 8 commits intoelastic:mainfrom
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Review: Interaction with the existing monolithic changelogThe new per-PR YAML changelog system and the existing No migration or replacement planThe existing No deduplicationNothing prevents the same change from appearing in both the monolithic file and a per-PR YAML entry. No release workflow
Format mismatchThe existing changelog uses AsciiDoc macros like Grouping mismatchThe existing file groups by Elasticsearch version ( SuggestionsTo be production-ready, this would need:
|
|
@edsavage , I am very excited about this change. However, this should be the first step to resolving #2217 and we need to decide on the complete plan on how integrate ML changeslog in the ES release docs process. I expect that some design decisions will extend/adjust the yaml schema that you are using now. Once we have this, we should ditch CHANGELOG.asciidoc completely and only use the single schema. I think a couple of things changed since 2022, which makes #2217 more approachable and relevant:
Can you please plan the required changes for the complete integration of the release doc processes, and identify the open questions we still need to answer before moving forward? |
Design Plan: Integrating ml-cpp Changelogs into the ES Release Notes PipelineFollowing up on @valeriy42's request to plan the complete integration of ml-cpp changelog entries into the Elasticsearch release documentation process, resolving #2217. Current State
Proposed DesignPhase 1: Per-PR YAML changelogs in ml-cppDevelopers add structured changelog entries with each ml-cpp PR. The schema should align with the ES changelog schema ( pr: 2914
summary: "Split build and test into separate pipeline steps"
area: Machine Learning
type: enhancement
issues: []Key schema decisions:
Auto-generation of changelog entriesIn the ES repo,
Developers can then customise the generated file if needed (e.g. adjusting the summary wording). This automation likely runs via Homer or another internal Elastic tool configured in Proposed mechanism —
This replicates the ES workflow while being self-contained — no dependency on Homer or external tooling. As an alternative (or complement), we could provide a CLI helper: # Generate changelog YAML from PR metadata
./dev-tools/generate_changelog.sh 2914Validation: CI validates entries against the schema on every PR (soft-fail initially, then hard-fail). Location: Skip logic: PRs labelled Phase 2: Integration with the ES release notes pipelineThree possible approaches, in order of preference: Option A — ES build pulls ml-cpp changelogs at bundle time (recommended) Extend
Requires a PR to Option B — CI pushes ml-cpp entries to the ES repo When an ml-cpp PR is merged, a GitHub Actions workflow creates a corresponding YAML file in the ES repo via PR:
Simpler to implement but adds cross-repo coupling and noise to the ES repo. Option C — Release-time script (interim) A script collects ml-cpp changelogs, converts them to ES-compatible format, and creates a single PR in the ES repo at release time. Less automation but lowest risk — good as an interim step while working toward Option A. Phase 3: Deprecate CHANGELOG.asciidocOnce the YAML system is integrated:
Phase 4: Backport considerationsChangelog YAML files travel with the PR — they are just files in the repo. When backporting:
Open Questions
Suggested Next Steps
|
|
Your plan looks good to me.
IMO, if we do this, we shouldn't rely on unwritten convention, and both PRs should be bundled together.
I don't understand this question. ES and ml-cpp have the same version boundary.
We handle it the same way as it is handled in ES and ml-cpp today.
We should backfill for the 3 branches we are supporting: main/9.4.0, 9.3.2, 9.2.7, and 8.19.13. This shouldn't be much With regard to #2217 , @pugnascotia do you see any problems with Phase 2 Option A (ES build pulls ml-cpp changelogs at bundle time) in Ed's comment above? |
I think this is the most appropriate option. |
Replace the monolithic CHANGELOG.md with per-PR YAML changelog files in docs/changelog/. Each PR that changes user-visible behaviour adds a small YAML file (<PR_NUMBER>.yaml) with structured metadata (area, type, summary). This eliminates merge conflicts in CHANGELOG.md and simplifies backports. Includes: - JSON schema for validating changelog entries - Python validation script (validate_changelogs.py) - Python bundler script (bundle_changelogs.py) for release notes - Gradle tasks: validateChangelogs, bundleChangelogs - Buildkite CI step (soft-fail during rollout) - Skip validation via >test, >refactoring, >docs, >build labels Made-with: Cursor
Made-with: Cursor
The validate-changelogs step ran on ml-check-style:2 (Alpine with only clang/bash/git, no Python), causing "pip: command not found". Switch the step to python:3.11-slim and install git on demand. Use python3 -m pip with --break-system-packages for PEP 668 compat. Made-with: Cursor
Replaces the ml-cpp-specific changelog schema with the exact
Elasticsearch changelog schema so that entries can be consumed
directly by the ES release notes pipeline (Phase 2 Option A).
Key changes:
- area enum: ES-wide values (most entries use "Machine Learning")
- type enum: adds breaking-java, known-issue, new-aggregation,
security, upgrade
- Adds highlight, breaking, and deprecation sub-objects
- pr/area not required for known-issue and security types
- Validator allows descriptive filenames for entries without a pr
- Bundler handles all new types and entries without pr/area
- AsciiDoc output uses {ml-pull} macros for consistency
Made-with: Cursor
Adds structured changelog entries for all changes in the active release branches: main/9.4.0, 9.3.x, 9.2.x, and 8.19.x. Also includes entries for recent hardening PRs (elastic#3008, elastic#3015) and the flaky test fix (elastic#3017) that were not yet in CHANGELOG.asciidoc. Made-with: Cursor
Update: Investigation findings and next stepsStep 1: Schema alignment — done ✅The changelog schema has been updated to be an exact copy of the Elasticsearch changelog schema. This means ml-cpp entries are directly consumable by the ES release notes pipeline with no transformation needed. Key changes:
Step 2: Backfill — done ✅Created changelog entries for all changes on active branches: main/9.4.0, 9.3.x, 9.2.x, 8.19.x (10 entries). Also includes recent hardening PRs (#3008, #3015) and flaky test fix (#3017). Step 3: Homer bot investigation — done ✅Correcting my earlier assumption: changelog YAML files are auto-generated in the ES repo by Homer ( How it works:
Configuration is per-repository in changelogs:
- repository: elastic/elasticsearch
applicableBranches: [...]
ignoredLabels: ['>test', '>refactoring', ...]
filteredLabels: [...]
areaOverrides: {...}To enable Homer for ml-cpp, someone with access to Proposed next steps
@valeriy42 @pugnascotia — thoughts on requesting Homer integration? Is this something the delivery team would be open to? |
e2d58c8 to
3050d2f
Compare
Correction: Homer changelog configuration locationThe changelog config is in github:
changelogs:
- repository: 'elastic/elasticsearch'
applicableBranches: [master, main, '8\.(x|\d+)', '7\.17']
ignoredLabels: ['>non-issue', '>refactoring', '>docs', '>test', '>test-failure', '>test-mute', '>tech-debt', ':Delivery/Build', ':Delivery/Cloud', ':Delivery/Tooling', 'backport', 'WIP']
filteredLabels: ['>new-field-mapper']
areaOverrides:
ml: Machine Learning
# ...To add ml-cpp, we'd need:
Example config for ml-cpp: - repository: 'elastic/ml-cpp'
applicableBranches: [main, '9\.\d+', '8\.\d+']
ignoredLabels: ['>non-issue', '>refactoring', '>docs', '>test', '>build']
areaOverrides: {}Since almost all ml-cpp entries will use |
Interim tool (Option C) to bridge ml-cpp changelogs into the ES release notes pipeline until the full BundleChangelogsTask integration (Option A) is implemented. The script copies changelog YAML entries from docs/changelog/ to the ES repo's docs/changelog/ with a 'ml-cpp-' filename prefix to avoid PR number collisions. Supports: - --dry-run to preview what would be exported - --target to specify the ES docs/changelog/ directory - --create-pr to automatically create a PR in the ES repo - --prune to delete source entries after a successful release - --version to label the export with a version number Made-with: Cursor
- Validate all entries against the JSON schema before exporting
- Verify the target directory is inside an ES checkout (checks for
build.gradle, settings.gradle, and docs/changelog/)
- Detect pre-existing files at the destination:
- Identical files are silently skipped
- Different files show a unified diff and prompt the user to
overwrite, skip, or abort the entire export
- Use the verified ES repo root for --create-pr instead of fragile
parent-of-parent path assumption
Made-with: Cursor
Adds the optional source_repo field to the changelog schema, matching the corresponding change in the Elasticsearch repo. This field tells the ES release notes generator which GitHub repo to use for PR links. The export script now injects source_repo: elastic/ml-cpp into exported entries automatically, so they link correctly in the ES release notes. Made-with: Cursor
Summary
Replaces the monolithic CHANGELOG.md approach with per-PR YAML changelog files, modelled after the Elasticsearch repository's changelog system.
Each PR that changes user-visible behaviour adds a small YAML file (
docs/changelog/<PR_NUMBER>.yaml) with structured metadata:What's included
docs/changelog/— directory for per-PR YAML entries, with a README explaining the format and a JSON schema for validationdev-tools/validate_changelogs.py— Python script that validates entries against the schema (filename convention, field types, enum values, PR number cross-check)dev-tools/bundle_changelogs.py— Python script that generates consolidated release notes (Markdown or AsciiDoc) from individual YAML entries, grouped by type and areavalidateChangelogsandbundleChangelogsfor local developer useformat_and_validation.yml.shas asoft_failstep during rollout, with automatic skip for PRs labelled>test,>refactoring,>docs, or>buildBenefits
Rollout plan
The CI step is set to
soft_fail: trueinitially, giving the team time to adopt the new workflow before making it mandatory.Test plan
validate_changelogs.pylocally with valid and invalid YAML filesbundle_changelogs.pymarkdown and asciidoc outputvalidateChangelogstask wiringMade with Cursor